/**
 * ****************************************************************************
 * $Author: Yegor Chemisov $
 * $Revision: 2.2 $
 * ****************************************************************************
 */
import javax.swing.*;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.util.Properties;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

class GameParameters extends Parameters implements ChangeListener, ActionListener
{
    public final static String[]    GRID_SIZE  = {"3x4", "4x6", "5x8", "6x9"};
    public final static int[]       ROWS       = {3, 4, 5, 6};
    public final static int[]       COLS       = {4, 6, 8, 9};
    public final static int         CUSTOM     = 4;
    public final static int         MAX_ROWS   = 8;
    public final static int         MAX_COLS   = 12;

    private int level;
    private int customRows;
    private int customCols;
    private int customDelay;

    private final String LEVEL          = "level";
    private final String SPEED          = "speed";
    private final String CUSTOM_ROWS    = "custom.rows";
    private final String CUSTOM_COLS    = "custom.cols";
    private final String CUSTOM_DELAY   = "custom.delay";

    private JButton[][] buttons = new JButton[MAX_ROWS + 1][MAX_COLS + 1];

    GameParameters()
    {
        super("jMemory.props", "jMemory Properties");
	    getParameters();
    }

    protected void setDefaults(Properties defaults)
    {
        defaults.put(LEVEL, "0");
        defaults.put(SPEED, "3");
        defaults.put(CUSTOM_ROWS, "3");
        defaults.put(CUSTOM_COLS, "4");
        defaults.put(CUSTOM_DELAY, "10");
    }

    protected void updateSettingsFromProperties()
    {
        try
        {
            level = Integer.parseInt(properties.getProperty(LEVEL));
            customRows = Integer.parseInt(properties.getProperty(CUSTOM_ROWS));
            customCols = Integer.parseInt(properties.getProperty(CUSTOM_COLS));
            customDelay = Integer.parseInt(properties.getProperty(CUSTOM_DELAY));
        }
        catch (NumberFormatException e)
        {
            // we don't care if the property was of the wrong format,
            // they've all got default values. So catch the exception
            // and keep going.
        }
    }

    protected void updatePropertiesFromSettings()
    {
        properties.put(LEVEL, new Integer(level).toString());
        properties.put(CUSTOM_ROWS, new Integer(customRows).toString());
        properties.put(CUSTOM_COLS, new Integer(customCols).toString());
        properties.put(CUSTOM_DELAY, new Integer(customDelay).toString());
    }

    public String toString()
    {
        return "[" + "Level=" + level + "]";
    }

    int getSleepTime()
    {
	    return (level == CUSTOM ? customDelay : getNumRows()) * 1000;
    }

    int getNumRows()
    {
	    return level == CUSTOM ? customRows: ROWS[level];
    }

    int getNumCols()
    {
	    return level == CUSTOM ? customCols: COLS[level];
    }

    int getNumButtons()
    {
	    return level == CUSTOM ?
                customRows * customCols :
                ROWS[level] * COLS[level];
    }

    void setLevel(int level)
    {
        this.level = level;
        saveParameters();
    }

    int getLevel()
    {
        return level;
    }

    public void showCustom()
    {

        JPanel panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));

        JPanel gridSize = new JPanel();
        gridSize.setLayout(new BoxLayout(gridSize, BoxLayout.Y_AXIS));

        gridSize.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createEtchedBorder(EtchedBorder.LOWERED),
                MAPConsts.RES.getString(GlobalRes.TITLE_CUSTOM_GRIDSIZE)));

        for (int r = 1; r <= MAX_ROWS; r++)
        {
            JPanel row = new JPanel();
            row.setLayout(new BoxLayout(row, BoxLayout.X_AXIS));

            for (int c = 1; c <= MAX_COLS; c++)
            {
                JButton btn = new JButton(" • ");
                buttons[r][c] = btn;
                btn.setBorder(BorderFactory.createMatteBorder(1,1,1,1, Color.LIGHT_GRAY ));
                if ( ( (r*c) % 2 == 0 ) && ( r*c > 2))
                {
                    btn.setActionCommand(r + "x" + c);
                    btn.addActionListener(this);
                }
                else
                {
                    btn.setEnabled(false);
                }
                row.setBorder(BorderFactory.createEmptyBorder(r==1?8:0, 17, r==MAX_ROWS?15:0 ,17));
                row.add(btn);
            }
            gridSize.add(row);
        }

        panel.add(gridSize);
        showCustomGridSize();

        JSlider framesPerSecond =
                new JSlider(JSlider.HORIZONTAL, 0, 30, customDelay);

        framesPerSecond.addChangeListener(this);

        //Turn on labels at major tick marks.
        framesPerSecond.setMajorTickSpacing(10);
        framesPerSecond.setMinorTickSpacing(1);
        framesPerSecond.setPaintTicks(true);
        framesPerSecond.setPaintLabels(true);
        framesPerSecond.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createEtchedBorder(EtchedBorder.LOWERED),
                MAPConsts.RES.getString(GlobalRes.TITLE_CUSTOM_DELAY)));

        panel.add(framesPerSecond);

        JOptionPane.showMessageDialog(StartGame.mainFrame , panel,
                MAPConsts.RES.getString(GlobalRes.TITLE_CUSTOM),
                JOptionPane.PLAIN_MESSAGE);
    }

    /** Listen to the slider. */
    public void stateChanged(ChangeEvent e)
    {
        JSlider source = (JSlider)e.getSource();
        if (!source.getValueIsAdjusting())
        {
            customDelay = source.getValue();
        }
    }

    static protected JSpinner addLabeledSpinner(Container c, String label, SpinnerModel model)
    {
        JLabel l = new JLabel(label);
        c.add(l);

        JSpinner spinner = new JSpinner(model);
        l.setLabelFor(spinner);
        c.add(spinner);

        return spinner;
    }

    private void showCustomGridSize()
    {
        for (int r = 1; r <= MAX_ROWS; r++)
            for (int c = 1; c <= MAX_COLS; c++)
                buttons[r][c].setBackground(
                        (r <= customRows && c <= customCols)
                        ? Color.WHITE : Color.LIGHT_GRAY);
    }

    public void actionPerformed(ActionEvent e)
    {
        String action  = e.getActionCommand();
        customRows = Integer.parseInt(action.substring(0,1));
        customCols = Integer.parseInt(action.substring(2));
        saveParameters();
        showCustomGridSize();
    }
}